package com.example.springmvc.controller;

import com.example.springmvc.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;

@Slf4j
@Controller// 使用 controller 注解，是为了和前端进行交互
@RequestMapping("/user")// 这就相当于是 一级路径
@ResponseBody// 返回的数据是一个 非静态页面 数据
public class UserController {
//   从配置文件中读取图片的保存路径
    @Value("${img.path}")
    private String imgPath;
    @RequestMapping(value = "/login3")
    public HashMap<String,Object> login3(@RequestBody UserInfo userInfo){
        HashMap<String,Object> result = new HashMap<>();// 记录返回结果
        int state = -1;// 状态记录
        int data = -1;// 如果 data 为1，则登录成功；否则，登录失败
        String msg = "未知错误";// 错误信息
        // spring中提供了 一个 StringUtils 类。里面提供了一个 判空的方法 hasLength，
        // hasLength 能够判断 字符串 是否为空，或者为 null。
        // 如果不为 空，也不为 null，则返回一个 true，反之，返回一个 false
        if(StringUtils.hasLength(userInfo.getUsername()) && StringUtils.hasLength(userInfo.getPassword())){
            if(userInfo.getUsername().equals("admin") && userInfo.getPassword().equals("admin")){// 登录成功
                data = 1;
                msg = "";
                state = 200;
            }else{// 用户名或密码错误！
                msg = "用户名或密码错误！";
            }
        }else{// 参数为空
            msg = "非法参数";
        }
        result.put("state",state);
        result.put("data",data);
        result.put("msg",msg);
        return  result;
    }

    @RequestMapping(value = "/login2")
    public HashMap<String,Object> login2(String username,String password){
        HashMap<String,Object> result = new HashMap<>();// 记录返回结果
        int state = -1;// 状态记录
        int data = -1;// 如果 data 为1，则登录成功；否则，登录失败
        String msg = "未知错误";// 错误信息
        // spring中提供了 一个 StringUtils 类。里面提供了一个 判空的方法 hasLength，
        // hasLength 能够判断 字符串 是否为空，或者为 null。
        // 如果不为 空，也不为 null，则返回一个 true，反之，返回一个 false
        if(StringUtils.hasLength(username) && StringUtils.hasLength(password)){
            if(username.equals("admin") && password.equals("admin")){// 登录成功
                data = 1;
                msg = "";
                state = 200;
            }else{// 用户名或密码错误！
                msg = "用户名或密码错误！";
            }
        }else{// 参数为空
            msg = "非法参数";
        }
        result.put("state",state);
        result.put("data",data);
        result.put("msg",msg);
        return  result;
    }

    @RequestMapping(value = "/setsession")
    public boolean setSession(HttpServletRequest request){
        boolean result = false;
        // 1、先获取到 HttpSession 对象
        // 获取 session 对象时，参数必须置为 true ( 默认值是 false )
        // true的意思：如果会话不存在，则创建一个会话
        HttpSession session = request.getSession(true);
        // 2、使用 setAttribut 方法 来设置会话属性
        session.setAttribute("userinfo","userinfo");
        result = true;
        return result;
    }

    @RequestMapping(value = "/getsession")
    public String getSession(HttpServletRequest request){
        String result = null;
        // 获取 session对象
        // 注意我们这里是获取 session对象，而不是设置。
        /// false：表示会话不存在，就不在去创建会话了。
        HttpSession session = request.getSession(false);
        if( session != null && session.getAttribute("userinfo") != null){
            // 因为获取的 value 值 是 一个 object 类型。所以需要就需要类型转换
            result = (String)session.getAttribute("userinfo");
        }
        return result;
    }

    @RequestMapping(value = "/getsession2")
    public String getSession2(@SessionAttribute(value = "userinfo",required = false) String str){
        return "注解方式："+ str;
    }

    @RequestMapping(value = "/header")
    public String getHeader(@RequestHeader("User-Agent") String str){
        return "注解形式 header: " + str;
    }

    @RequestMapping(value = "/cookie")
    public String getCookie(@CookieValue("message") String str){
        return "Cookie Value: " + str;
    }

    @GetMapping("/sayhi")// 这就相当于是二级路径
    public String sayHi(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
        return "Hello World!  " + httpServletRequest.getParameter("name");
    }

//    @RequestMapping(method = RequestMethod.POST,value = "/sayhi2")
    @PostMapping("/sayhi2")
    public String sayHi2(){
        return "你好，世界！";
    }
    @RequestMapping(value = "/getuserbyid")
    public UserInfo getUserById(Integer id){
        // 不查数据库，以为代码的形式，人造一个UserInfo对象，作为查询结果返回
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id == null ? 0 : id);// id 就set为 传过来的参数
        userInfo.setUsername("张三");
        userInfo.setAge(18);
        // 注意 密码 一般是不返回的，为了安全
        return userInfo;
    }

    @RequestMapping(value = "/echo")
    public String echo(String username,String password){
        return "用户名: " + username + "| 密码:" + password;
    }

    @RequestMapping(value = "/echo2")
    public String echo2(@RequestBody UserInfo userInfo){
        return "用户信息："+ userInfo;
    }

    @RequestMapping(value = "echo3")
    public String echo3(@RequestParam(value = "name",required = false) String username){
        return "用户姓名：" + username;
    }

    @RequestMapping("/echo4/{name}/{password}")
    public String echo4(@PathVariable String heroname,@PathVariable String password){
        return "name: "+ heroname + "password: " + password;
    }

    @RequestMapping(value = "/upimg")
    public boolean upImg(Integer uid, @RequestPart("img") MultipartFile file){
        boolean result = false;
        // 先获取 图片名称
        String fileName = file.getOriginalFilename();
        // 从 最后一个 . 位置，向后截取 剩余部分 ( 获取文件格式 )
        fileName = fileName.substring(fileName.lastIndexOf("."));
        // 利用 UUID 对 文件名称 进行处理，得到唯一的文件名称
        // 处理: 生成唯一的随机数，与 文件后缀 进行拼接
        // 最终的结果 就是 文件的名称
        fileName = UUID.randomUUID().toString() + fileName;
        try {
            file.transferTo(new File(imgPath + fileName));
            result = true;
        } catch (IOException e) {
            // 记得在类上面加上一个 @Slf4j 注解，要不然你是使用不了log来打印日志的。
            log.error("上传图片失败！" + e.getMessage());
//            e.printStackTrace();
        }
        return  result;
    }

//    @RequestMapping(value = "/upimg")
//    public boolean upImg(Integer uid, @RequestPart("img") MultipartFile file){
//        boolean result = false;
//        // 保存图片 到 本地目录（工作中就是服务器，别人把图片提到我服务器上存储，其实更严格来说，这算是上传图片功能）
//        // 承载对象 MultipartFile file 中 提供一个 transferTo 方法，将对象中的数据存储一个指定位置
//        // transferTo 方法 的参数，要求是一个 File 对象，所以，我们需要先 new File 对象，将存储路径作为其参数。
//        // 同时 存储的过程是可能会失败的，因此它会出现异常，我们使用 try catch 来 包裹
//        try {
//            file.transferTo(new File("G:/img.png"));
//            result = true;
//        } catch (IOException e) {
//            // 记得在类上面加上一个 @Slf4j 注解，要不然你是使用不了log来打印日志的。
//            log.error("上传图片失败！" + e.getMessage());
////            e.printStackTrace();
//        }
//        return  result;
//    }
}
